Skip to content

feat(editor): let copilot narrow the API references panel during tutorials#3304

Open
Ethanlita wants to merge 2 commits into
goplus:devfrom
Ethanlita:feat/api-reference-filter
Open

feat(editor): let copilot narrow the API references panel during tutorials#3304
Ethanlita wants to merge 2 commits into
goplus:devfrom
Ethanlita:feat/api-reference-filter

Conversation

@Ethanlita

@Ethanlita Ethanlita commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

What & why

During a tutorial course, the left-side API References panel shows the full catalog of spx APIs, which can overwhelm a learner. This PR lets the copilot narrow that panel to only the APIs a course actually needs, and restores it automatically when the course ends.

The panel is filtered while the user is being guided through a course, and returns to showing everything once they leave "tutorial mode" (i.e. the copilot session ends).

How it works (data flow)

copilot emits  <api-reference-filter names="onStart, say, move">
      │  (custom element, rendered in the copilot panel)
      ▼
codeEditor.setAPIReferenceFilter(predicate)      ← generic, reactive state on CodeEditor
      ▼
APIReferenceController.filteredItems             ← synchronous derived view over loaded items
      ▼
APIReferenceUI re-renders (empty categories collapse automatically)

Clearing: the editor watches copilot.currentSession and resets the filter whenever the session ends or switches.

Changes (by layer)

Generic editor (xgo-code-editor) — no knowledge of copilot/tutorials

  • api-reference.ts: new APIReferenceFilter = (item) => boolean type.
  • code-editor.ts: reactive apiReferenceFilter + setAPIReferenceFilter() .
  • ui/api-reference/index.ts: filteredItems — a synchronous derivation over the already-loaded items, so filter changes update the UI reactively without re-running the async provider. Falls back to the full list if a filter matches nothing.
  • ui/api-reference/APIReferenceUI.vue: render filteredItems instead of items.

Editor ↔ copilot seam (editor/copilot)

  • New ApiReferenceFilter.ts: an api-reference-filter custom element that reaches the editor via useCodeEditorRef() (same mechanism as the existing CodeLink/CodeChange elements) and sets the filter on mount. APIs are matched by name (e.g. onStart, say) — the vocabulary the model already knows from the spx-project skill — so no extra catalog/tool is needed.
  • index.ts: register the element next to the other editor copilot elements; clear the filter on copilot session change.

Tutorial

  • tutorial.ts: the course prompt now instructs the copilot to narrow the panel to the union of APIs the whole course uses (not just the current step), set once at the start and kept stable. The tutorial module holds no filter state and does not depend on the editor.

Design notes

  • The generic xgo-code-editor / API Reference layer stays unaware of tutorial; the only coupling lives in the two existing connection points (editor/copilot and the tutorial prompt), bridged through copilot.
  • Filtering is a synchronous derivation, so it rides Vue reactivity rather than re-triggering the async API load.
  • The filter is a session-scoped transient: cleared on session end, so it can never persist into normal (non-tutorial) editing.

Testing

  • Manual: in the editor, asking the copilot to "show only onStart and say" narrows the panel; starting a coding course narrows it to the course's APIs; finishing/leaving the course restores the full list.
  • npm run type-check, npm run lint, Prettier — all pass.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an API reference filtering feature to narrow down the visible APIs in the "API References" panel, helping guide users during tutorial steps. It adds an ApiReferenceFilter component, registers it as a copilot custom element, updates tutorial instructions, and integrates the filter state into the CodeEditor and APIReferenceController. Feedback on the changes highlights two key issues: first, in APIReferenceUI.vue, the computed property incorrectly expects an oldValue argument (which is not supported in Vue 3), breaking the UI stability logic; second, in ApiReferenceFilter.ts, the filter does not re-apply when the names prop changes, requiring a watch on both codeEditorRef and props.names to ensure reactivity.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread spx-gui/src/components/editor/copilot/ApiReferenceFilter.ts Outdated

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two findings in the new API reference filter code, plus a documentation mismatch from the chapter-8 renaming:

Tutorial chapters 1–7 (onStart removal) and chapter 4 scope example: content and code are consistent. No issues.

Fallback-to-full-list behavior in filteredItems: sound and well-documented.

oldValue in computed: valid on Vue 3.4+ (this project uses Vue ^3.5.25). Not an issue.

See inline comments for specifics.

Findings without inline locations

  • tutorial/codeKiko/summary.md:51: Broken TOC link — title and anchor both stale after the section was renamed in commit 3.

Comment thread spx-gui/src/components/editor/copilot/ApiReferenceFilter.ts Outdated
Ethanlita and others added 2 commits June 23, 2026 17:48
Add a generic, reactive API reference filter on CodeEditor that the copilot
can drive via a new `api-reference-filter` custom element (matching APIs by
name). The filter is a synchronous derived view over the already-loaded items,
so it updates reactively without re-running the async provider, and is cleared
automatically when the copilot session ends or switches (e.g. a tutorial course
finishes) — keeping the generic editor unaware of tutorials.

Tutorial courses instruct the copilot to narrow the panel to the union of APIs
the whole course uses, so learners are not distracted by unrelated APIs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the on-mount + codeEditorRef watch with a single immediate watch
on both the editor ref and the `names` prop, so the filter updates when the
copilot revises the element in place, not only on mount.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

export type Props = {
/** Comma-separated API names to keep visible. Empty string shows all. */
names: string

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不同的 API definition 可能有相同的 name(不过 ID 是各自唯一的),比如 say wordsay word, seconds 的 name 都是 say,通过 name 控制的话这俩要么都留要么都不留,是你预期的吗?


// The API reference filter is transient state scoped to a copilot session: clear it whenever the
// session ends or switches (e.g. a tutorial course finishes), so a filter never leaks past its context.
d.addDisposer(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这边是把 apiReferenceFilter 的控制放在 copilot 这里,而不是 tutorial 中,考虑的是?

我感觉放 tutorial 中可能好点,主要是暂时没想到在 tutorial 外 copilot 需要控制 apiReferenceFilter 的合理用例

* re-running the async provider. Falls back to the full list when the filter matches
* nothing, to avoid leaving the panel empty.
*/
get filteredItems() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

建议 filter 后的数据叫 items(未 filter 的数据可以叫别的名字,另外定义为 private field),支持 filter 是 APIReferenceController 的内部逻辑,不需要让消费方(如 APIReferenceUI.vue)感知到

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants